package cn.itcast.nems.journal.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.itcast.ic.common.bean.Page;
import cn.itcast.ic.common.exception.v2.BizExceptionProducer;
import cn.itcast.nems.common.PageQueryModel;
import cn.itcast.nems.common.account.AccountHolder;
import cn.itcast.nems.common.enumeration.NemsErrorBodyEnum;
import cn.itcast.nems.common.util.NumberUtil;
import cn.itcast.nems.employee.dao.bean.EmployeeGroupBean;
import cn.itcast.nems.journal.api.JournalRenewalLineApi;
import cn.itcast.nems.journal.dto.JournalRenewalLineDTO;
import cn.itcast.nems.journal.dto.JournalRenewalLineDiscountDTO;
import cn.itcast.nems.journal.enumeration.JournalRenewalLineStateEnum;
import cn.itcast.nems.journal.service.JournalRenewalLineService;
import cn.itcast.nems.manager.util.CustomBeanUtil;
import cn.itcast.nems.studentrecord.constant.DiscountScopeTypeEnum;
import cn.itcast.nems.studentrecord.dao.condition.ApprovalType;
import cn.itcast.nems.studentrecord.dao.dataobject.JournalRenewalLineDO;
import cn.itcast.nems.studentrecord.dao.dataobject.JournalRenewalLineDiscountDO;
import cn.itcast.nems.studentrecord.dao.entity.JournalRenewalLine;
import cn.itcast.nems.studentrecord.dao.entity.StudentRecord;
import cn.itcast.nems.studentrecord.dao.mapper.JournalRenewalLineDiscountMapper;
import cn.itcast.nems.studentrecord.dao.mapper.JournalRenewalLineMapper;
import cn.itcast.nems.studentrecord.dao.mapper.StudentRecordMapper;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 短训升班凭单-行 服务实现类
 * </p>
 *
 * @author liyong
 * @since 2023-11-14
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class JournalRenewalLineServiceImpl extends ServiceImpl<JournalRenewalLineMapper, JournalRenewalLine> implements JournalRenewalLineService, JournalRenewalLineApi {
    private final JournalRenewalLineDiscountMapper journalRenewalLineDiscountMapper;
    private final JournalRenewalLineMapper journalRenewalLineMapper;
    private final StudentRecordMapper studentRecordMapper;

    @Override
    public List<JournalRenewalLineDTO> findListByRenewalId(String renewalId) {
        List<JournalRenewalLineDO> renewalLineList = getBaseMapper().findListByRenewalId(renewalId);
        log.info("根据凭单ID查询凭单行列表：{}，{}" ,renewalId , JSON.toJSONString(renewalLineList));
        return Objects.requireNonNullElse(renewalLineList, new ArrayList<JournalRenewalLineDO>()).stream().map(this::transferJournalRenewalLineDTO).sorted().toList();
    }

    private JournalRenewalLineDTO transferJournalRenewalLineDTO(JournalRenewalLineDO item) {
        log.info("【查询升级凭单详情学员列表】行学员数据：{}", JSON.toJSONString(item));
        JournalRenewalLineDTO lineDTO = CustomBeanUtil.copyProperties(item, new JournalRenewalLineDTO());
        // 升级班级原价格
        lineDTO.setTargetClazzOriginalAmount(NumberUtil.convertToYuan(item.getTargetClazzOriginalAmount()));
        // 优惠合计
        lineDTO.setTargetClazzDiscountAmount(NumberUtil.convertToYuan(item.getTargetClazzDiscountAmount()));
        // 应付金额
        lineDTO.setTargetClazzAmountDue(NumberUtil.convertToYuan(item.getTargetClazzAmountDue()));
        // 检查是否有学籍信息
        if (Objects.nonNull(item.getTargetStudentRecordId())) {
            StudentRecord studentRecord = studentRecordMapper.selectById(item.getTargetStudentRecordId());
            lineDTO.setStudentRecordState(Objects.nonNull(studentRecord) ? studentRecord.getState() : null);
        }
        List<JournalRenewalLineDiscountDO> discountList = journalRenewalLineDiscountMapper.findDiscountsByRenewalIdAndLineId(item.getJournalRenewalId(), item.getId());
        // 区分是普通优惠还是个人优惠  ， 根据 字段：”discountScopeType“ 判断是”普通优惠“还是”个人优惠“，参考枚举值：一般｜NORMAL、个人｜PERSONAL
        discountList = Objects.requireNonNullElse(discountList, new ArrayList<>());
        lineDTO.setDiscountList(discountList.stream()
                .filter(i -> DiscountScopeTypeEnum.NORMAL.name().equalsIgnoreCase(i.getDiscountScopeType()))
                .map(dc -> {
                    JournalRenewalLineDiscountDTO discountDTO = CustomBeanUtil.copyProperties(dc, new JournalRenewalLineDiscountDTO());
                    discountDTO.setDiscountAmount(NumberUtil.convertToYuan(dc.getDiscountAmount()));
                    return discountDTO;
                }).sorted().toList());
        lineDTO.setDiscountCouponList(discountList.stream()
                .filter(i -> DiscountScopeTypeEnum.PERSONAL.name().equalsIgnoreCase(i.getDiscountScopeType()))
                .map(dc -> {
                    JournalRenewalLineDiscountDTO discountDTO = CustomBeanUtil.copyProperties(dc, new JournalRenewalLineDiscountDTO());
                    discountDTO.setDiscountAmount(NumberUtil.convertToYuan(dc.getDiscountAmount()));
                    return discountDTO;
                }).sorted().toList());
        return lineDTO;
    }

    @Override
    public Page<JournalRenewalLineDTO> findPageListByRenewalId(PageQueryModel<JournalRenewalLineDTO> queryModel, ApprovalType approvalType) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<JournalRenewalLineDO> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>();
        page.setCurrent(queryModel.getPageNumber());
        page.setSize(queryModel.getPageSize());
        JournalRenewalLineDTO lineDTO = Objects.nonNull(queryModel.getCondition()) ? queryModel.getCondition() : new JournalRenewalLineDTO();
        JournalRenewalLineDO lineDO = CustomBeanUtil.copyProperties(lineDTO, new JournalRenewalLineDO());
        List<EmployeeGroupBean> employeeGroups = null;
        //        if (approvalType == ApprovalType.ALL) {
        //            if (!AccountHolder.hasEmployeeGroups()) {
        //                return Page.of(queryModel.getPageNumber(), queryModel.getPageSize(), 0, new ArrayList<>());
        //            }
        //            employeeGroups = AccountHolder.getEmployeeGroups();
        //        }
        IPage<JournalRenewalLineDO> pageData = getBaseMapper().findPageListByRenewalIdAndCondition(page, lineDO, employeeGroups);
        List<JournalRenewalLineDTO> list = CollectionUtil.isEmpty(pageData.getRecords()) ?
                null : pageData.getRecords().stream().map(this::transferJournalRenewalLineDTO).toList();
        return Page.of(queryModel.getPageNumber(), queryModel.getPageSize(), Long.valueOf(pageData.getTotal()).intValue(), list);
    }

    @Override
    public String findJobStudentRecordId(String id) {
        return super.getBaseMapper().selectJobStudentRecordId(id);
    }

    @Override
    public String findLineIdByJobStudentRecordId(String studentRecordId) {
        return super.getBaseMapper().selectLineIdByJobStudentRecordId(studentRecordId);
    }

    @Override
    public String findLineIdByOrderId(String orderId) {
        return super.getBaseMapper().selectLineIdByOrderId(orderId);
    }

    @Override
    public void updateStateById(@NonNull String id, @NonNull String state) {
        Assert.notNull(JournalRenewalLineStateEnum.valueOf(state), BizExceptionProducer.produce(NemsErrorBodyEnum.ENUM_ERROR));
        JournalRenewalLine renewalLine = getBaseMapper().selectById(id);
        Assert.notNull(renewalLine, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "升级凭单行ID：" + id));
        int updateResult = getBaseMapper().update(null, new LambdaUpdateWrapper<JournalRenewalLine>().eq(JournalRenewalLine::getId, id).set(JournalRenewalLine::getState, state));
        Assert.isTrue(updateResult > 0, BizExceptionProducer.produce(NemsErrorBodyEnum.DATABASE_UPDATE_ERROR, "升级凭单行ID：" + id));
    }

    @Override
    public JournalRenewalLineDTO findById(@NonNull String id) {
        JournalRenewalLine line = getBaseMapper().selectById(id);
        return CustomBeanUtil.copyProperties(line, new JournalRenewalLineDTO());
    }

    @Override
    public void updateState(String id, JournalRenewalLineStateEnum state) {
        String modifiedBy = AccountHolder.getRequiredAccount();
        this.journalRenewalLineMapper.updateState(id, state.toString(), modifiedBy);
    }
}
